package com.binecy.reactor;

import com.binecy.bean.Goods;
import com.binecy.bean.Order;
import com.binecy.bean.User;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.SynchronousSink;

import java.util.concurrent.CountDownLatch;

public class FluxBase {

    private Logger logger = LoggerFactory.getLogger(FluxBase.class);

    @Test
    public void test() throws InterruptedException {
        Mono<User> userMono = Mono.create(sink -> {

            new Thread(() -> {
                logger.info("get user start");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("get user end");
                sink.success(new User(1L,"hello"));
            }).start();

        });


        Mono<Goods> goodsMono = Mono.create(sink -> {
            new Thread(() -> {
                logger.info("get goods start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("get goods end");
                sink.success(new Goods(1,"apple", 500));
            }).start();

        });

        Mono<Order> orderMono = Mono.create(sink -> {
           new Thread(() -> {
               logger.info("get order start");
               try {
                   Thread.sleep(2000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               logger.info("get order end");
               sink.success(new Order());
           }).start();
        });




        orderMono.zipWhen(o -> {
            return userMono;
        }, (o, u) -> {
            o.setUserName(u.getName());
           return o;
        }).subscribe(o -> System.out.println(o));

//        Flux.just().zipWith()

//        orderMono.zipWith(goodsMono, (o, g) -> {
//            System.out.println("start set goodsName");
//            o.setGoodsName(g.getName());
//            return o;
//        }).zipWith(userMono, (o, u) -> {
//            System.out.println("start set userName");
//            o.setUserName(u.getName());
//            return o;
//        }).subscribe(o -> System.out.println(o));




//        goodsMono.zipWith(userMono, (g, u) -> {
//            Order o = new Order();
//            o.setGoodsName(g.getName());
//            o.setUserName(u.getName());
//            return o;
//        }).subscribe(o -> System.out.println(o));

//        userMono.then(goodsMono).log().subscribe(a -> System.out.println(a.getClass()));

//
//        Mono<Order> user2 = userMono.flatMap(user -> {
//           return Mono.just(new Order(user.getName(), null));
//        });
//
//        Mono<Order> goods2 = goodsMono.flatMap(goods -> {
//            return Mono.just(new Order(null, goods.getName()));
//        });
//
//        Order order = new Order();
//        Mono<Order> fluxMono = Mono.just(new Order());
//        fluxMono.flatMap(o -> {
//
//
//            userMono.subscribe(u -> o.setUserName(u.getName()));
//            goodsMono.subscribe(g -> o.setGoodsName(g.getName()));
//
//
//            return Mono.just(o);
//        }).subscribe(o -> System.out.println(o));

//        Flux.just(user2).collect(goods2, null);

//
//        Order order = new Order();
//        Mono.create(sink -> {
//            userMono.subscribe(user -> order.setUserName(user.getName()));
//            goodsMono.subscribe(goods -> order.setGoodsName(goods.getName()));
//            sink.success(order);
//        }).subscribe(a -> System.out.println(a));



//        Flux.generate(new Order(), (Order order, SynchronousSink sink) -> {
//            userMono.subscribe(user -> order.setUserName(user.getName()));
//            goodsMono.subscribe(goods -> order.setGoodsName(goods.getName()));
//            sink.next(order);
//            sink.complete();
//            return order;
//        }).subscribe(a -> System.out.println(a));

//        Mono.when(userMono,goodsMono).subscribe(a -> System.out.println(a.getClass()));

        new CountDownLatch(1).await();
    }
}
